package com.yjzx.util.common.util.batch.merging;

import com.yjzx.util.common.util.BeanUtils.BaseInterface;

import java.lang.reflect.Field;
import java.util.function.Function;

/**
 * @author yjzx
 * @date 2024/6/18
 * @description ReportData
 */
public class DataMerging<T, U extends Comparable<U>, R> {
    /**
     * 返回值类型
     */
    BaseInterface<R> reference;
    /**
     * 执行方法参数
     */
    T param;
    /**
     * 指定的节点
     */
    U u;
    /**
     * 节点的前一个值
     */
    U uPreceding;
    /**
     * 节点前执行的方法
     */
    Function<T, R> oldReportParam;
    /**
     * 节点后执行的方法
     */
    Function<T, R> newReportParam;

    public DataMerging(DataMerging<T, U, R> data) {
        if (data != null) {
            data.check();
            this.reference = data.reference;
            this.param = data.param;
            this.u = data.u;
            this.uPreceding = data.uPreceding;
            this.oldReportParam = data.oldReportParam;
            this.newReportParam = data.newReportParam;
        } else {
            throw new NullPointerException("data is null");
        }
    }

    public DataMerging(BaseInterface<R> reference, T param, U u, U uPreceding, Function<T, R> oldReportParam, Function<T, R> newReportParam) {
        this.reference = reference;
        this.param = param;
        this.u = u;
        this.uPreceding = uPreceding;
        this.oldReportParam = oldReportParam;
        this.newReportParam = newReportParam;
        check();
    }

    public void setReference(BaseInterface<R> reference) {
        this.reference = reference;
    }

    public void setParam(T param) {
        this.param = param;
    }

    public void setU(U u) {
        this.u = u;
    }

    public void setuPreceding(U uPreceding) {
        this.uPreceding = uPreceding;
    }

    public void setOldReportParam(Function<T, R> oldReportParam) {
        this.oldReportParam = oldReportParam;
    }

    public void setNewReportParam(Function<T, R> newReportParam) {
        this.newReportParam = newReportParam;
    }

    void check() {
        for (Field field : getClass().getDeclaredFields()) {
            try {
                field.setAccessible(true);
                if (field.get(this) == null) {
                    throw new NullPointerException(getClass().getName() + " " + field.getName() + " is null");
                }
            } catch (IllegalAccessException ignored) {
            }
        }
    }

}
